package com.zp.self.module.level_4_算法练习.算法.双指针.左右指针;

import java.util.ArrayList;
import java.util.List;

/**
 * @author By ZengPeng
 */
public class 力扣_986_区间列表的交集 {
    //测试
    public static void main(String[] args) {
        int[][] ints;
//                ints = new 力扣_986_区间列表的交集().intervalIntersection(
//                new int[][]{{0, 2}, {5, 10}, {13, 23}, {24, 25}},
//                new int[][]{{1, 5}, {8, 12}, {15, 24}, {25, 26}});
//        System.out.println(ints);
        ints = new 力扣_986_区间列表的交集().intervalIntersection(
                new int[][]{{14,16}},
                new int[][]{{7,13},{16,20}});
        System.out.println(ints);
    }

    /**
    题目：给定两个由一些 闭区间 组成的列表，firstList 和 secondList ，其中 firstList[i] = [starti, endi] 而 secondList[j] = [startj, endj] 。
     每个区间列表都是成对 不相交 的，并且 已经排序 。
     返回这 两个区间列表的交集 。
     形式上，闭区间 [a, b]（其中 a <= b）表示实数 x 的集合，而 a <= x <= b 。
     两个闭区间的 交集 是一组实数，要么为空集，要么为闭区间。例如，[1, 3] 和 [2, 4] 的交集为 [2, 3] 。

     示例 1：
     输入：firstList = [[0,2],[5,10],[13,23],[24,25]], secondList = [[1,5],[8,12],[15,24],[25,26]]
     输出：[[1,2],[5,5],[8,10],[15,23],[24,24],[25,25]]

     示例 2：
     输入：firstList = [[1,3],[5,9]], secondList = []
     输出：[]

     示例 3：
     输入：firstList = [], secondList = [[4,8],[10,12]]
     输出：[]

     示例 4：
     输入：firstList = [[1,7]], secondList = [[3,10]]
     输出：[[3,7]]

    分析：【P 💝💝💝💝】
       1.双指针：记录前两个集合判断的结果old[0],old[1]，与下一个较小集合先做比较:new[0],new[1]；
                  优点：比较过程中始终保持: old[0]<new[0]
                  -- 执行用时：3 ms, 在所有 Java 提交中击败了91.29%的用户

    边界值 & 注意点：
       1. 不要漏掉新区间
       2. 最后一次比较
     **/
    public int[][] intervalIntersection(int[][] firstList, int[][] secondList) {
        if(firstList.length==0 || secondList.length==0)return new int[0][0];
        List<int[]> res = new ArrayList<>();
        int indexA=0,indexB=0;
        int[] old;int[] newA;
        if(firstList[indexA][0]<=secondList[indexB][0])
            old=firstList[indexA++];
        else
            old=secondList[indexB++];
        while (indexA<firstList.length || indexB<secondList.length){
            if(indexA==firstList.length)
                newA =secondList[indexB++];
            else if(indexB==secondList.length)
                newA =firstList[indexA++];
            else {
                if(firstList[indexA][0]<=secondList[indexB][0])
                    newA =firstList[indexA++];
                else
                    newA =secondList[indexB++];
            }
            if(old==newA)break;//一个集合没值了，且新旧相等
            if(old[1]<newA[0]){//无交点，重新找old,突然想到：直接将newA给old,就行了
                old=newA;
                continue;
            }
            if(old[1]>newA[1]){//合并
                res.add(newA);
                old=new int[]{newA[1],old[1]};
            }else {//找到交集、找到新的old
                res.add(new int[]{newA[0],old[1]});
                old=new int[]{old[1],newA[1]};
            }
        }
        return res.toArray(new int[res.size()][2]);
    }
}
